﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.IO;
using System.IO.Pipes;
using System.Threading;

namespace CmdSrv
{
    public class CmdSrv
    {
        public enum CMD_SRV_TYPE
        {
            WIN_NAMED_PIPES
        }

        public delegate uint cmd_exec_func_delegate(string cmd);

        cmd_exec_func_delegate cmd_exec_func = null;

        Thread serviceThread;

        public CmdSrv(CMD_SRV_TYPE srv_t, cmd_exec_func_delegate exec_func)
        {
            cmd_exec_func = exec_func;

            switch (srv_t)
            {
                case CMD_SRV_TYPE.WIN_NAMED_PIPES:
                    serviceThread = new Thread(new ThreadStart(named_pipe_service));
                    serviceThread.IsBackground = true;
                    serviceThread.Start();
                    break;
            }
        }

        public void CmdSrvStop()
        {
            serviceThread.Abort();
        }

        private void named_pipe_service()
        {
            NamedPipeClientStream nSndPipe = null;
            NamedPipeServerStream nRcvPipe = new NamedPipeServerStream("\\OMX_AL_CMD_PIPE", PipeDirection.In);
            byte[] buffer = new byte[1024];
            int cnt = 0;
            bool srv_running = true;

            nRcvPipe.WaitForConnection();

            while (srv_running)
            {
                cnt = nRcvPipe.Read(buffer, 0, 1023);
                uint status = 0;
                String sss = System.Text.ASCIIEncoding.ASCII.GetString(buffer, 0, cnt);
                String cmd = "";
                String prm = "";
                if (sss.Length >= 2)
                {
                    cmd = sss.Remove(2);
                    if(sss.Length > 3)
                        prm = sss.Remove(0,3);
                }

                switch (cmd)
                {
                    case "-f":
                        if (cmd_exec_func != null)
                        {
                            status = cmd_exec_func(prm);
                            if (nSndPipe != null)
                            {
                                nSndPipe.WriteByte((byte)(status >> (8 * 3)));
                                nSndPipe.WriteByte((byte)(status >> (8 * 2)));
                                nSndPipe.WriteByte((byte)(status >> (8 * 1)));
                                nSndPipe.WriteByte((byte)(status >> (8 * 0)));
                            }
                        }
                        break;
                    case "-s":
                        srv_running = false;
                        break;
                    case "-c":
                        if (nSndPipe != null)
                            nSndPipe.Close();
                        nSndPipe = new NamedPipeClientStream(prm);
                        break;
                    default:
                        break;
                }
            }
            if (nSndPipe != null)
                nSndPipe.Close();
            nRcvPipe.Disconnect();

            if (nRcvPipe != null && nRcvPipe.IsConnected)
                nRcvPipe.Close();
        }
    }
}
